Warning
Beta — APIs, inputs, and output formats may change without notice. Pin to a specific commit hash in production workflows.
Existing scanners (pip-audit, osv-scanner, grype) tell you what is vulnerable but not why it's in your project. When a transitive dependency has a CVE, you're left guessing which direct dependency pulled it in and whether you can actually fix it.
venomcheck answers: who brought this in, and can I upgrade past it?
Found 3 vulnerabilities in 2 packages
| Package | Version | Vulnerability | Fix | Dependency Chain |
|--------------|---------|----------------|--------|-----------------------------------------------|
| cryptography | 42.0.0 | CVE-2024-26130 | 42.0.4 | boto3 > botocore > urllib3 > cryptography |
| requests | 2.31.0 | CVE-2024-35195 | 2.32.0 | flask-admin > requests |
| certifi | 2023.7 | CVE-2024-39689 | 2024.7 | **httpx** (pinned ==0.24.0, blocked) |
### Summary
- 2 fixable via dependency upgrade
- 1 blocked by upstream constraints
Tip
Pin to commit hashes, not tags. Tags are mutable — a compromised upstream can repoint a tag to malicious code. Commit SHAs are immutable.
Auto-detected when uv.lock is present — no extra config needed.
- uses: nevoodoo/venomcheck@<COMMIT_SHA> # v0
with:
mode: uv # optional, auto-detectedRequires packages to be installed first so venomcheck can read their metadata.
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.12"
- run: pip install -r requirements.txt
- uses: nevoodoo/venomcheck@<COMMIT_SHA> # v0
with:
mode: pip- uses: nevoodoo/venomcheck@<COMMIT_SHA> # v0
with:
mode: auto # auto | uv | pip
fail-on-vulns: true # exit 1 if vulnerabilities found
comment-on-pr: true # post/update PR comment
ignore-ids: "CVE-2024-39689,GHSA-xxxx"
ignore-packages: "certifi"
exclude-dev: false # set true to skip dev dependencies- uses: nevoodoo/venomcheck@<COMMIT_SHA> # v0
with:
path: services/api- uses: nevoodoo/venomcheck@<COMMIT_SHA> # v0
id: scan
with:
fail-on-vulns: false
- run: echo "Found ${{ steps.scan.outputs.vuln-count }} vulnerabilities"# uv project
python -m venomcheck.cli --mode uv --path /path/to/project
# pip project
python -m venomcheck.cli --mode pip --path /path/to/project
# JSON output
python -m venomcheck.cli --format json
# Ignore specific packages or CVEs
python -m venomcheck.cli --ignore-packages certifi --ignore-ids CVE-2024-39689| Input | Required | Default | Description |
|---|---|---|---|
mode |
no | auto |
Detection mode: auto, uv, or pip |
path |
no | . |
Path to directory containing uv.lock or requirements.txt |
fail-on-vulns |
no | true |
Exit with failure if vulnerabilities found |
comment-on-pr |
no | true |
Post/update PR comment with report |
ignore-ids |
no | "" |
Comma-separated vulnerability IDs to ignore |
ignore-packages |
no | "" |
Comma-separated package names to skip |
| Output | Description |
|---|---|
vuln-count |
Number of vulnerabilities found |
report |
Markdown report content |
- Detects project type —
uv.lockpresent → uv mode, otherwise pip mode - Builds the dependency graph — parses
uv.lock(TOML) or reads installed package metadata viaimportlib.metadata - Queries OSV.dev — checks all packages against the largest open-source vulnerability database
- Traces dependency chains — walks the graph back to the direct dependency that introduced each finding
- Classifies findings — fixable (upgrade path exists), blocked (pinned upstream), or ignored
- Reports — markdown table with actionable remediation paths
- Minimal dependencies — pip mode uses only the stdlib (
importlib.metadata,urllib.request); uv mode additionally requiresuvfor lock file resolution - Composite action — no Docker, fast startup, works on all runner OSes
- OSV.dev — free, no auth, same DB used by pip-audit and
uv audit - Marker-isolated PR comments — uses an HTML marker to find/update its own comment without clobbering other bots
For PR comments, the workflow needs:
permissions:
pull-requests: writeAvoiding double runs
The comment-on-pr feature requires pull_request triggers. A common pattern:
on:
push:
branches: [main]
pull_request:push fires only for main, pull_request fires for PRs — no double runs.
Note
This is a beta release. Known limitations:
- Duplicate CVE entries may appear when multiple vulnerability databases (GHSA, PYSEC) track the same issue
- pip mode depends on packages being installed in the current environment
- Version comparison uses a simple numeric parser that may not handle all PEP 440 edge cases
Contributions and bug reports are welcome.
This project was originally written for @populationgenomics as python-package-scanner. It has been copied here to allow independent development — adding features, experimenting with new directions, and diverging from the upstream version's scope. Built with help from Claude.